package com.tools.service.workflow.impl;

import com.tools.pojo.workflow.bo.FlowNode;
import com.tools.pojo.workflow.bo.NodeExecutionResult;
import com.tools.pojo.workflow.po.FlowInstance;
import com.tools.pojo.workflow.po.FlowTransition;
import com.tools.service.workflow.FlowRouterService;
import com.tools.service.workflow.FlowTransitionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class FlowRouterServiceImpl implements FlowRouterService {

    private final FlowTransitionService flowTransitionService;
    private final ExpressionParser expressionParser = new SpelExpressionParser();

    /**
     * 获取下一个要执行的节点
     */
    @Override
    public String getNextNode(FlowInstance flowInstance, String currentNodeCode,
                              Map<String, List<FlowTransition>> transitionMap,
                              NodeExecutionResult currentResult) {

        List<FlowTransition> outTransitions = transitionMap.get(currentNodeCode);
        if (outTransitions == null || outTransitions.isEmpty()) {
            log.warn("节点 {} 没有出线连线", currentNodeCode);
            return null;
        }

        // 根据当前节点类型决定路由策略
        FlowNode currentNode = getCurrentNodeFromContext(flowInstance); // 需要从上下文获取当前节点信息

        if (currentNode != null) {
            return switch (currentNode.getNodeType()) {
                case "CONDITION" -> routeConditionalNode(flowInstance, outTransitions, currentResult);
                case "PARALLEL" -> routeParallelNode(flowInstance, outTransitions, currentResult);
                default -> routeDefaultNode(outTransitions);
            };
        }

        // 默认路由策略
        return routeDefaultNode(outTransitions);
    }

    /**
     * 路由条件分支节点
     */
    private String routeConditionalNode(FlowInstance flowInstance,
                                        List<FlowTransition> transitions,
                                        NodeExecutionResult currentResult) {

        // 创建SPEL评估上下文
        StandardEvaluationContext spelContext = createEvaluationContext(flowInstance, currentResult);

        // 按优先级评估条件连线
        for (FlowTransition transition : transitions) {
            if (evaluateTransitionCondition(transition, spelContext)) {
                log.info("条件分支路由: {} -> {} [条件: {}]",
                        transition.getSourceNode(),
                        transition.getTargetNode(),
                        transition.getConditionExpression());
                return transition.getTargetNode();
            }
        }

        // 如果没有条件满足，尝试返回默认连线
        FlowTransition defaultTransition = findDefaultTransition(transitions);
        if (defaultTransition != null) {
            log.info("条件分支路由: 使用默认连线 -> {}", defaultTransition.getTargetNode());
            return defaultTransition.getTargetNode();
        }

        log.warn("条件分支路由: 没有找到满足条件的连线，也没有默认连线");
        return null;
    }

    /**
     * 路由并行分支节点
     */
    private String routeParallelNode(FlowInstance flowInstance,
                                     List<FlowTransition> transitions,
                                     NodeExecutionResult currentResult) {
        // TODO: 实现并行分支逻辑
        // 这里需要更复杂的逻辑来管理并行分支的执行
        // 暂时返回第一个连线目标
        if (!transitions.isEmpty()) {
            return transitions.get(0).getTargetNode();
        }
        return null;
    }

    /**
     * 路由默认节点（无条件分支）
     */
    private String routeDefaultNode(List<FlowTransition> transitions) {
        // 优先查找默认连线
        FlowTransition defaultTransition = findDefaultTransition(transitions);
        if (defaultTransition != null) {
            return defaultTransition.getTargetNode();
        }

        // 如果没有默认连线，返回第一个连线的目标节点
        if (!transitions.isEmpty()) {
            return transitions.get(0).getTargetNode();
        }

        return null;
    }

    /**
     * 评估连线条件
     */
    private boolean evaluateTransitionCondition(FlowTransition transition,
                                                StandardEvaluationContext context) {

        if (!"CONDITION".equals(transition.getTransitionType())) {
            return false; // 非条件连线不参与条件评估
        }

        String conditionExpr = transition.getConditionExpression();
        if (conditionExpr == null || conditionExpr.trim().isEmpty()) {
            return false; // 无条件表达式
        }

        // 特殊处理：默认条件
        if ("true".equalsIgnoreCase(conditionExpr.trim()) ||
                "default".equalsIgnoreCase(conditionExpr.trim())) {
            return true;
        }

        try {
            Expression expression = expressionParser.parseExpression(conditionExpr);
            Boolean result = expression.getValue(context, Boolean.class);
            return Boolean.TRUE.equals(result);
        } catch (Exception e) {
            log.warn("条件表达式评估失败: {}, 错误: {}", conditionExpr, e.getMessage());
            return false;
        }
    }

    /**
     * 查找默认连线
     */
    private FlowTransition findDefaultTransition(List<FlowTransition> transitions) {
        return transitions.stream()
                .filter(t -> "DEFAULT".equals(t.getTransitionType()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 创建SPEL评估上下文
     */
    private StandardEvaluationContext createEvaluationContext(FlowInstance flowInstance,
                                                              NodeExecutionResult currentResult) {
        StandardEvaluationContext context = new StandardEvaluationContext();

        // 设置流程实例变量
        context.setVariable("flowInstance", flowInstance);
        context.setVariable("businessKey", flowInstance.getBusinessKey());

        // 设置当前执行结果变量
        context.setVariable("currentResult", currentResult);
        context.setVariable("success", currentResult.isSuccess());
        context.setVariable("message", currentResult.getMessage());
        context.setVariable("data", currentResult.getData());

        // 设置流程上下文数据
        Map<String, Object> contextData = parseContextData(flowInstance.getContextData());
        for (Map.Entry<String, Object> entry : contextData.entrySet()) {
            context.setVariable(entry.getKey(), entry.getValue());
        }

        return context;
    }

    /**
     * 从上下文中获取当前节点信息
     * 注意：这是一个简化实现，实际需要从流程实例或执行路径中获取
     */
    private FlowNode getCurrentNodeFromContext(FlowInstance flowInstance) {
        // 这里需要根据实际情况实现
        // 可以从执行路径中获取当前节点信息，或者通过其他方式
        return null;
    }

    /**
     * 解析上下文数据（简化实现）
     */
    @Override
    public Map<String, Object> parseContextData(String contextDataJson) {
        // 这里需要ObjectMapper，简化实现返回空Map
        return Map.of();
    }

    /**
     * 获取所有可能的下一节点（用于并行分支等复杂场景）
     */
    @Override
    public List<String> getAllNextNodes(FlowInstance flowInstance, String currentNodeCode,
                                        Map<String, List<FlowTransition>> transitionMap) {

        List<FlowTransition> outTransitions = transitionMap.get(currentNodeCode);
        if (outTransitions == null || outTransitions.isEmpty()) {
            return List.of();
        }

        return outTransitions.stream()
                .map(FlowTransition::getTargetNode)
                .distinct()
                .toList();
    }

    /**
     * 验证节点路由是否有效
     */
    @Override
    public boolean validateNodeRoute(FlowInstance flowInstance, String sourceNode, String targetNode,
                                     Map<String, List<FlowTransition>> transitionMap) {

        List<FlowTransition> outTransitions = transitionMap.get(sourceNode);
        if (outTransitions == null) {
            return false;
        }

        return outTransitions.stream()
                .anyMatch(transition -> targetNode.equals(transition.getTargetNode()));
    }
}
